<template>
  <div
    class="rich_editor"
  >
    <div
      ref="elQuill"
      :style="{height: height, width: width}"
    />
  </div>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref, PropType, unref, watchEffect } from 'vue'
import Quill, { QuillOptionsStatic } from 'quill'
import { isUnDef } from '@/utils/is'
import { toolbar } from './default-opt'
import 'quill/dist/quill.snow.css'

export default defineComponent({
  name: 'QuillEditor',
  props: {
    modelValue: {
      type: String as PropType<string>,
      default: ''
    },
    height: {
      type: String as PropType<string>,
      default: '10vh'
    },
    width: {
      type: String as PropType<string>,
      default: ''
    },
    placeholder: {
      type: String as PropType<string>,
      default: '请输入内容'
    },
    toolbar: {
      type: Object as PropType<IDictionary<any>>,
      default: () => toolbar
    },
    modules: {
      type: Object as PropType<IDictionary<any>>,
      default: () => { return {} }
    },
    theme: {
      type: String as PropType<string>,
      default: 'snow'
    },
    disabled: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    debug: {
      type: Boolean as PropType<boolean>,
      default: false
    },
    /** 最大输入字符长度 */
    maxLength: {
      type: Number as PropType<number>,
      default: -1
    }
  },
  emits: ['update:modelValue', 'change'],
  setup(props, context) {
    const elQuill = ref<Nullable<Element>>(null)
    const textLength = ref(0)
    let update = false
    const config: QuillOptionsStatic = {
      placeholder: props.placeholder,
      debug: props.debug, // process.env.NODE_ENV === 'development',
      theme: props.theme,
      readOnly: props.disabled,
      modules: {
        toolbar: props.toolbar,
        ...props.modules
      }
    }
    onMounted(() => {
      /* eslint-disable-next-line */
      const quill = new Quill(unref(elQuill) as Element, config)
      quill.on('text-change', (delta, oldDelta, source) => {
        if (source === 'user') {
          let htmlText = quill.root.innerHTML
          // 获取当前字符长度
          const length = quill.getLength() - 1
          textLength.value = length
          // 截取
          if (props.maxLength > 0 && length > props.maxLength) {
            const o = delta.ops
            const retain = o[0].retain as number
            let len = 0
            if (isUnDef(retain)) {
              len = (o[0].insert as string).length
            } else {
              len = (o[1].insert as string).length
            }
            // 中文输入超出时会有问题
            quill.deleteText(retain || 0, len, 'user')
          }
          if (quill.root.innerText.trim() === '') htmlText = ''
          context.emit('update:modelValue', htmlText)
          update = true
          context.emit('change', quill.root)
        }
      })
      watchEffect(() => {
        // 从 text-change 来的不更新 临时解决方案
        if (update) {
          update = false
        } else {
          quill.clipboard.dangerouslyPasteHTML(props.modelValue)
        }
      })
    })
    return {
      elQuill,
      textLength
    }
  }
})
</script>
